/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jtplugin;
import info.chrm.jtalker.*;
import java.lang.reflect.Method;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

/**
 *
 * @author christoph
 */
public class TicTacToe implements JTalkerClientPlugInInterface, JTalkerClientCommandInterface{

    private static int ENEMY_REMOTE = 0;
    private static int ENEMY_AI = 1;
    private boolean gameIsActive = false;
    private javax.swing.ImageIcon myIcon = null;

    public int winCounterUser = 0;
    public int winCounterEnemy = 0;

    // The parent translator object
    private JTalkerClientPluginConnector myParentObject = null;
    private TTTWindow myTttWindow;
    private TTTSettings myTttSettings;

    public String myName = "";    
    public String enemyName = "";

    public TicTacToe() {
        this.myTttWindow = new TTTWindow(this);
        this.myTttSettings = new TTTSettings(this);
        this.myIcon = new javax.swing.ImageIcon(getClass().getResource("/jtplugin/ttticon.png"));
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Main method for debuggig only!
        //(new TicTacToe().getMainFrame()).setVisible(true);
    }

    public JFrame getMainFrame() {
        if(this.myParentObject != null) {
            this.myTttSettings.setUserList(this.myParentObject.getOnlineUsers());            
        }

        if(!this.gameIsActive)
            return this.myTttSettings;
        else
            return this.myTttWindow;
    }

    public JFrame getSettingsFrame() {
        if(this.myParentObject != null) {
            this.myTttSettings.setUserList(this.myParentObject.getOnlineUsers());            
        }
        
        return this.myTttSettings;
    }

    public ImageIcon getIcon() {
        return this.myIcon;
    }

    public String getName() {
        return "Tic-Tac-Toe";
    }

    public String getDescription() {
        return "The player who succeeds in placing three respective marks in a horizontal, vertical or diagonal row wins the game.";
    }

    public boolean setParentObject(JTalkerClientPluginConnector _connector) {
        this.myParentObject = _connector;
        this.myParentObject.registerForCommandResponse(this);
        this.myName = this.myParentObject.getUserName();
	    System.out.println("+ (TicTacToe) Ok, parent object initialized: " + _connector);
	    return true;
    }

    public void unload() {
        this.myParentObject.deRegisterForCommandResponse(this);
        this.myParentObject = null;
    }

    public Method[] getCommandMethods() {
         Method [] myMethods = new Method[4];

          try {
             myMethods[0] =
                this.getClass().getDeclaredMethod("inviteForGame", new Class [] {String.class});
             myMethods[1] =
                this.getClass().getDeclaredMethod("turn", new Class [] {String.class});
             myMethods[2] =
                this.getClass().getDeclaredMethod("restartGame");
             myMethods[3] =
                this.getClass().getDeclaredMethod("cancelRunningGame");
          } catch (Exception _e) {
                _e.printStackTrace();
                return null;
          }

        return myMethods;
    }

    //////////////////// Command Methods ////////////////////

    /** Invite for a game */
    public String inviteForGame(String _userName) {
        System.out.println("----> inviteForGame()");

        if(this.gameIsActive)
            return "NOTOK: Another Game is running";

        this.winCounterUser = 0;
        this.winCounterEnemy = 0;

        int retVal = JOptionPane.showConfirmDialog(null, "The user " + _userName + " wants to play\nTic-Tac-Toe with you.\nDo you agree?", "Want to play?", JOptionPane.YES_NO_OPTION);

        if(retVal == JOptionPane.YES_OPTION) {
            this.enemyName = _userName;
            this.myTttWindow.startNewGame(false, 2, ENEMY_REMOTE, -1, this.enemyName);
            this.myTttWindow.setVisible(true);
            this.gameIsActive = true;

            return "OK";
        } else {
            return "NOTOK: Rejected";
        }
    }
    /** Recieves a turn from remote user */
    public String turn(String _index) {
        System.out.println("----> turn()");

        if(!this.gameIsActive)
            return "NOTOK: Invite first";

        if(this.myTttWindow.setExternalAction(Integer.parseInt(_index)))
            return "OK";
        else
            return "NOTOK: Unknown error occured";
    }

    /** Restarts the game with the current enemy and settings */
    public String restartGame() {
        System.out.println("----> restartGame()");

        this.myTttWindow.startNewGame(false, 1, ENEMY_REMOTE, -1, this.enemyName);
        this.myTttWindow.setVisible(true);
        this.gameIsActive = true;

        return "OK";
    }

    /** Stops a running game */
    public String cancelRunningGame() {
        System.out.println("----> cancelRunningGame()");

        this.gameIsActive = false;
        this.myTttWindow.setVisible(false);
        return "OK";
    }

    //////////////////////////////////////////////////////////////

    public Method[] getUserMethods() {
        return null;
    }

    public boolean setCommandAnswer(String _id, String _from, String _content) {
        if(_id.equals("msgTTTInvite")) {
            if(_content.equals("OK")) {
                if(this.gameIsActive) {
                    return false;
                }

                System.out.println("----> Got OK for INVITE");
                this.winCounterUser = 0;
                this.winCounterEnemy = 0;

                this.myTttWindow.setVisible(true);

                this.myTttWindow.startNewGame(true, 
                        1, this.myTttSettings.getGameType(),
                        this.myTttSettings.getSelectedAI(),
                        this.myTttSettings.getSelectedUser());
                
                this.gameIsActive = true;
                return true;

            } else {
                System.out.println("----> *** Got NOTOK for invite.");
                JOptionPane.showMessageDialog(this.myTttWindow, "Can't start a game.\nThe message was:\n" + _content, "Can't start a game.", JOptionPane.INFORMATION_MESSAGE);
            }

            return false;
        }

        if(_id.equals("msgTTTRestart")) {
            if(_content.equals("OK")) {
                if(this.gameIsActive) {
                    return false;
                }

                System.out.println("----> Got OK for RESTART");

                this.myTttWindow.setVisible(true);

                this.myTttWindow.startNewGame(true,
                        1, this.myTttSettings.getGameType(),
                        this.myTttSettings.getSelectedAI(),
                        this.myTttSettings.getSelectedUser());

                this.gameIsActive = true;
                return true;

            } else {
                System.out.println("----> *** Got NOTOK for invite.");
                JOptionPane.showMessageDialog(this.myTttWindow, "Can't restart a game.\nThe message was:\n" + _content, "Can't start a game.", JOptionPane.INFORMATION_MESSAGE);
            }

            return false;
        }

        if(_id.equals("msgTTTCancel")) {
            if(_content.equals("OK")) {
                System.out.println("----> Got OK for CANCEL - cancel too.");
                this.gameIsActive = false;
                this.myTttWindow.setVisible(false);
            }
        }

        return false;
    }

    /** Will be called from the settings menu */
    public void startNewGame(boolean _restart) {
        if(_restart && this.myName.length() > 0 && this.enemyName.length() > 0) {
            System.out.println("----> Restarting the game with the same settings");
            this.gameIsActive = false;
            this.myParentObject.sendMessage("jtplugin.TicTacToe::restartGame()",
                    this.enemyName, "command", "", "msgTTTRestart");

            return;
        }

        if(this.myTttSettings.getGameType() == ENEMY_REMOTE) {
            // Remote Game            
            this.enemyName = this.myTttSettings.getSelectedUser();
            this.gameIsActive = false;
            this.myParentObject.sendMessage("jtplugin.TicTacToe::inviteForGame("+this.myName+")",
                    this.enemyName, "command", "", "msgTTTInvite");
        } else {
            // Local Game
            this.myTttWindow.startNewGame(true,
                        1,
                        this.myTttSettings.getGameType(),
                        this.myTttSettings.getSelectedAI(),
                        "AI");

            this.enemyName = "AI";
            this.myTttWindow.setVisible(true);
            this.gameIsActive = true;
        }
    }

    /** Will be called from the gema window */
    public void endCurrentGame() {
        if(this.myTttSettings.getGameType() == ENEMY_REMOTE) {
            // Remote Game
            this.myParentObject.sendMessage("jtplugin.TicTacToe::cancelRunningGame()",
                    this.enemyName, "command", "", "msgTTTCancel");

            this.gameIsActive = false;
        } else {
            // Local Game
            this.myTttWindow.startNewGame(true,
                        1, this.myTttSettings.getGameType(),
                        this.myTttSettings.getSelectedAI(),
                        "AI");

            this.myTttWindow.setVisible(false);
            this.gameIsActive = false;
        }
    }

    public void setTurn(int _field) {
        if(this.myTttSettings.getGameType() == ENEMY_REMOTE) {
            // Remote Game
            this.myParentObject.sendMessage("jtplugin.TicTacToe::turn(" + _field + ")",
                    this.enemyName, "command", "", "msgTTTTurn");
        }
    }
}
